import { Page } from "puppeteer-core";
import { brower } from "../lib/brower";
import { delay } from "../lib/delay";

/**
 * 通过这个类实现对 page 对象的控制
 */
export class PageControler {
    private pageItem: PageItem[] = [];


    public async initPage(n: number = 1) {
        for (let i = 0; i < n; i++) {
            try {

                const page = await (await brower).newPage()
                if (!page) {
                    throw new Error("page 为空")
                }
                this.pageItem.push(new PageItem(page))
            } catch (e) {
                console.log("🚀 ~ file: PageController.ts ~ line 24 ~ PageControler ~ addPage ~ e", e)
                console.error("创建page失败");

            }
        }

    }
    /**
     * 等待一个空闲 page
     * @returns {Page} page
     */
    public async waitSparePage(): Promise<PageItem> {
        // 等待最少一个空闲的页面
        while (this.pageItem.filter(e => e.status == PageItem.Freeing).length == 0) {
            await delay(100);
        }
        // 将所有的 page 包装对象通过 time（使用时间进行升序排序）
        this.pageItem.sort((a, b) => {
            if (a.status != b.status) {
                return a.status == PageItem.Freeing ? -1 : 1;
            } else {
                return a.time - b.time;
            }
        })

        return this.pageItem[0]
    }

    /**
     * 返回所有的页面
     * @returns {Page[]} 返回所有的page
     */
    public getPages(): Page[] {
        return this.pageItem.map(e => e.page);
    }
}


/**
 * 对 page 对象的一层封装
 */
class PageItem {
    /** 使用中 */
    static readonly Using = false;
    /** 空闲中 */
    static readonly Freeing = true;
    constructor(public page: Page, public time: number = Date.now(), public status: boolean = PageItem.Freeing) {

    }

    /**
     * 开始使用 page 对象，使用完毕后需要调用 back() 方法归还，否则 page 处于占用状态
     * @returns 
     */
    get() {
        this.status = PageItem.Using;
        this.time = Date.now();
        return this.page
    }
    /**
     * 返回 page ,使其空闲
     */
    back() {
        this.status = PageItem.Freeing;
    }
}

